//
//  ViewController.m
//  GCDBarrier
//
//  Created by fangyuan ding on 2020/10/26.
//  Copyright © 2020 fangyuan ding. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self initUI];
}
- (void)initUI{
    UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(100, 100, 80, 40)];
    [self.view addSubview:btn];
    [btn addTarget:self action:@selector(btnclick) forControlEvents:UIControlEventTouchUpInside];
    [btn setTitle:@"barrier" forState:UIControlStateNormal];
    [btn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [btn setBackgroundColor:[UIColor redColor]];
    
    
    UIButton *gcdBtn = [[UIButton alloc]initWithFrame:CGRectMake(100, 200, 80, 40)];
    [self.view addSubview:gcdBtn];
    [gcdBtn addTarget:self action:@selector(gcdBtnclick) forControlEvents:UIControlEventTouchUpInside];
    [gcdBtn setTitle:@"gcd" forState:UIControlStateNormal];
    [gcdBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
    [gcdBtn setBackgroundColor:[UIColor redColor]];
    
}
- (void)btnclick{
    // 并发队列
    dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
    // 异步执行
    dispatch_async(queue, ^{
    for (int i = 0; i < 3; i++) {
    NSLog(@"栅栏：并发异步1 %@",[NSThread currentThread]);
    }
    });
    dispatch_async(queue, ^{
    for (int i = 0; i < 3; i++) {
    NSLog(@"栅栏：并发异步2 %@",[NSThread currentThread]);
    }
    });
    dispatch_barrier_async(queue, ^{
    NSLog(@"------------barrier------------%@", [NSThread currentThread]);
    NSLog(@"******* 并发异步执行，但是34一定在12后面 *********");
    });
    dispatch_async(queue, ^{
    for (int i = 0; i < 3; i++) {
    NSLog(@"栅栏：并发异步3 %@",[NSThread currentThread]);
    }
    });
    dispatch_async(queue, ^{
    for (int i = 0; i < 3; i++) {
    NSLog(@"栅栏：并发异步4 %@",[NSThread currentThread]);
    }
    });
//    GCD延时执行
//    当需要等待一会再执行一段代码时，就可以用到这个方法了：dispatch_after。
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)),
    dispatch_get_main_queue(), ^{
    // 5秒后异步执行
    NSLog(@"我已经等待了5秒！");
    });
//    GCD实现代码只执行一次
//    使用dispatch_once能保证某段代码在程序运行过程中只被执行1次。可以用来设计单例。
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
    NSLog(@"程序运行过程中我只执行了一次！");
    });
   
    // dispatch_apply几乎同时遍历多个数字
    dispatch_apply(7, queue, ^(size_t index) {
    NSLog(@"dispatch_apply：%zd======%@",index, [NSThread currentThread]);
    });
}
//GCD队列组
//异步执行几个耗时操作，当这几个操作都完成之后再回到主线程进行操作，就可以用到队列组
//了。
//队列组有下面几个特点：
//1 所有的任务会并发的执行(不按序)。 2 所有的异步函数都添加到队列中，然后再纳入队列组的监听范围。
//3 使用dispatch_group_notify函数，来监听上面的任务是否完成，如果完成, 就会调用这个方法。
- (void)gcdBtnclick{
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
    NSLog(@"队列组：有一个耗时操作完成！");
    });
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
    NSLog(@"队列组：有一个耗时操作完成！");
    });
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    NSLog(@"队列组：前面的耗时操作都完成了，回到主线程进行相关操作");
    });
}
@end
